﻿namespace Voxel2Unity
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using System.Runtime.InteropServices;
    using UnityEngine;

    public class QbData
    {
        public uint ColorFormat;
        public uint Compressed;
        public List<QbMatrix> MatrixList;
        public uint NumMatrixes;
        public uint Version;
        public uint VisibleMask;
        public uint ZAxisOrientation;

        private Color BGR(int color)
        {
            int num = 0xff & color;
            int num2 = 0xff00 & color;
            num2 = num2 >> 8;
            int num3 = 0xff0000 & color;
            num3 = num3 >> 0x10;
            return new Color(((float) num3) / 255f, ((float) num2) / 255f, ((float) num) / 255f);
        }

        public void Flip(Voxel2Unity.Axis _axis)
        {
            Vector3 sizeAll = this.SizeAll;
            for (int i = 0; i < this.MatrixList.Count; i++)
            {
                QbMatrix matrix = this.MatrixList[i];
                for (int j = 0; j < ((_axis != Voxel2Unity.Axis.X) ? ((float) matrix.SizeX) : (matrix.SizeX * 0.5f)); j++)
                {
                    for (int k = 0; k < ((_axis != Voxel2Unity.Axis.Y) ? ((float) matrix.SizeY) : (matrix.SizeY * 0.5f)); k++)
                    {
                        for (int m = 0; m < ((_axis != Voxel2Unity.Axis.Z) ? ((float) matrix.SizeZ) : (matrix.SizeZ * 0.5f)); m++)
                        {
                            int num5 = (_axis != Voxel2Unity.Axis.X) ? j : ((matrix.SizeX - j) - 1);
                            int num6 = (_axis != Voxel2Unity.Axis.Y) ? k : ((matrix.SizeY - k) - 1);
                            int num7 = (_axis != Voxel2Unity.Axis.Z) ? m : ((matrix.SizeZ - m) - 1);
                            int num8 = matrix.Voxels[j, k, m];
                            matrix.Voxels[j, k, m] = matrix.Voxels[num5, num6, num7];
                            matrix.Voxels[num5, num6, num7] = num8;
                        }
                    }
                }
                matrix.PosX = (_axis != Voxel2Unity.Axis.X) ? matrix.PosX : ((((int) sizeAll.x) - matrix.PosX) - matrix.SizeX);
                matrix.PosY = (_axis != Voxel2Unity.Axis.Y) ? matrix.PosY : ((((int) sizeAll.y) - matrix.PosY) - matrix.SizeY);
                matrix.PosZ = (_axis != Voxel2Unity.Axis.Z) ? matrix.PosZ : ((((int) sizeAll.z) - matrix.PosZ) - matrix.SizeZ);
                this.MatrixList[i] = matrix;
            }
        }

        public VoxData GetVoxData()
        {
            VoxData data = new VoxData();
            Vector3 sizeAll = this.SizeAll;
            data.SizeX = (int) sizeAll.x;
            data.SizeY = (int) sizeAll.y;
            data.SizeZ = (int) sizeAll.z;
            data.Voxels = new int[data.SizeX, data.SizeY, data.SizeZ];
            List<Color> list = new List<Color> {
                new Color()
            };
            for (int i = 0; i < this.MatrixList.Count; i++)
            {
                int num3;
                int num4;
                QbMatrix matrix;
                QbMatrix matrix5;
                QbMatrix matrix6;
                QbMatrix matrix7;
                int num2 = 0;
                goto Label_0194;
            Label_0079:
                num3 = 0;
                goto Label_0172;
            Label_0081:
                num4 = 0;
                goto Label_0150;
            Label_0089:
                matrix = this.MatrixList[i];
                int num5 = matrix[num2, num3, num4];
                if (num5 != 0)
                {
                    Color item = (this.ColorFormat != 0) ? this.BGR(num5) : this.RGB(num5);
                    int index = list.IndexOf(item);
                    if (index == -1)
                    {
                        list.Add(item);
                        index = list.Count - 1;
                    }
                    QbMatrix matrix2 = this.MatrixList[i];
                    QbMatrix matrix3 = this.MatrixList[i];
                    QbMatrix matrix4 = this.MatrixList[i];
                    data.Voxels[num2 + matrix2.PosX, num3 + matrix3.PosY, num4 + matrix4.PosZ] = index + 1;
                }
                num4++;
            Label_0150:
                matrix5 = this.MatrixList[i];
                if (num4 < matrix5.SizeZ)
                {
                    goto Label_0089;
                }
                num3++;
            Label_0172:
                matrix6 = this.MatrixList[i];
                if (num3 < matrix6.SizeY)
                {
                    goto Label_0081;
                }
                num2++;
            Label_0194:
                matrix7 = this.MatrixList[i];
                if (num2 < matrix7.SizeX)
                {
                    goto Label_0079;
                }
            }
            data.Palatte = list.ToArray();
            return data;
        }

        private Color RGB(int color)
        {
            int num = 0xff & color;
            int num2 = 0xff00 & color;
            num2 = num2 >> 8;
            int num3 = 0xff0000 & color;
            num3 = num3 >> 0x10;
            return new Color(((float) num) / 255f, ((float) num2) / 255f, ((float) num3) / 255f);
        }

        public void Rotate(Voxel2Unity.Axis _axis, bool reverse = false)
        {
            for (int i = 0; i < this.MatrixList.Count; i++)
            {
                int num8;
                int num9;
                int num11;
                int num12;
                int num14;
                int num15;
                QbMatrix matrix = this.MatrixList[i];
                int sizeX = matrix.SizeX;
                int sizeY = matrix.SizeY;
                int sizeZ = matrix.SizeZ;
                int posX = matrix.PosX;
                int posY = matrix.PosY;
                int posZ = matrix.PosZ;
                int[,,] numArray = null;
                switch (_axis)
                {
                    case Voxel2Unity.Axis.X:
                        sizeY = matrix.SizeZ;
                        sizeZ = matrix.SizeY;
                        posY = matrix.PosZ;
                        posZ = matrix.PosY;
                        numArray = new int[sizeX, sizeY, sizeZ];
                        num8 = 0;
                        goto Label_00F9;

                    case Voxel2Unity.Axis.Y:
                        sizeX = matrix.SizeZ;
                        sizeZ = matrix.SizeX;
                        posX = matrix.PosZ;
                        posZ = matrix.PosX;
                        numArray = new int[sizeX, sizeY, sizeZ];
                        num11 = 0;
                        goto Label_01D8;

                    case Voxel2Unity.Axis.Z:
                        sizeX = matrix.SizeY;
                        sizeY = matrix.SizeX;
                        posX = matrix.PosY;
                        posY = matrix.PosX;
                        numArray = new int[sizeX, sizeY, sizeZ];
                        num14 = 0;
                        goto Label_02B6;

                    default:
                    {
                        continue;
                    }
                }
            Label_009C:
                num9 = 0;
                while (num9 < matrix.SizeY)
                {
                    for (int j = 0; j < matrix.SizeZ; j++)
                    {
                        numArray[num8, j, num9] = matrix.Voxels[num8, num9, j];
                    }
                    num9++;
                }
                num8++;
            Label_00F9:
                if (num8 < matrix.SizeX)
                {
                    goto Label_009C;
                }
                matrix.SizeY = sizeY;
                matrix.SizeZ = sizeZ;
                matrix.PosY = posY;
                matrix.PosZ = posZ;
                matrix.Voxels = numArray;
                this.MatrixList[i] = matrix;
                continue;
            Label_017B:
                num12 = 0;
                while (num12 < matrix.SizeY)
                {
                    for (int k = 0; k < matrix.SizeZ; k++)
                    {
                        numArray[k, num12, num11] = matrix.Voxels[num11, num12, k];
                    }
                    num12++;
                }
                num11++;
            Label_01D8:
                if (num11 < matrix.SizeX)
                {
                    goto Label_017B;
                }
                matrix.SizeX = sizeX;
                matrix.SizeZ = sizeZ;
                matrix.PosX = posX;
                matrix.PosZ = posZ;
                matrix.Voxels = numArray;
                this.MatrixList[i] = matrix;
                continue;
            Label_0259:
                num15 = 0;
                while (num15 < matrix.SizeY)
                {
                    for (int m = 0; m < matrix.SizeZ; m++)
                    {
                        numArray[num15, num14, m] = matrix.Voxels[num14, num15, m];
                    }
                    num15++;
                }
                num14++;
            Label_02B6:
                if (num14 < matrix.SizeX)
                {
                    goto Label_0259;
                }
                matrix.SizeX = sizeX;
                matrix.SizeY = sizeY;
                matrix.PosX = posX;
                matrix.PosY = posY;
                matrix.Voxels = numArray;
                this.MatrixList[i] = matrix;
            }
            switch (_axis)
            {
                case Voxel2Unity.Axis.X:
                    if (!reverse)
                    {
                        this.Flip(Voxel2Unity.Axis.Y);
                        break;
                    }
                    this.Flip(Voxel2Unity.Axis.Z);
                    break;

                case Voxel2Unity.Axis.Y:
                    if (!reverse)
                    {
                        this.Flip(Voxel2Unity.Axis.Z);
                        break;
                    }
                    this.Flip(Voxel2Unity.Axis.X);
                    break;

                case Voxel2Unity.Axis.Z:
                    if (!reverse)
                    {
                        this.Flip(Voxel2Unity.Axis.X);
                        break;
                    }
                    this.Flip(Voxel2Unity.Axis.Y);
                    break;
            }
        }

        public Vector3 SizeAll
        {
            get
            {
                int a = 0;
                int num2 = 0;
                int num3 = 0;
                for (int i = 0; i < this.MatrixList.Count; i++)
                {
                    if (i == 0)
                    {
                        QbMatrix matrix = this.MatrixList[i];
                        QbMatrix matrix2 = this.MatrixList[i];
                        a = matrix.SizeX + matrix2.PosX;
                        QbMatrix matrix3 = this.MatrixList[i];
                        QbMatrix matrix4 = this.MatrixList[i];
                        num2 = matrix3.SizeY + matrix4.PosY;
                        QbMatrix matrix5 = this.MatrixList[i];
                        QbMatrix matrix6 = this.MatrixList[i];
                        num3 = matrix5.SizeZ + matrix6.PosZ;
                    }
                    else
                    {
                        QbMatrix matrix7 = this.MatrixList[i];
                        QbMatrix matrix8 = this.MatrixList[i];
                        a = Mathf.Max(a, matrix7.SizeX + matrix8.PosX);
                        QbMatrix matrix9 = this.MatrixList[i];
                        QbMatrix matrix10 = this.MatrixList[i];
                        num2 = Mathf.Max(num2, matrix9.SizeY + matrix10.PosY);
                        QbMatrix matrix11 = this.MatrixList[i];
                        QbMatrix matrix12 = this.MatrixList[i];
                        num3 = Mathf.Max(num3, matrix11.SizeZ + matrix12.PosZ);
                    }
                }
                return new Vector3((float) a, (float) num2, (float) num3);
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct QbMatrix
        {
            public string Name;
            public int SizeX;
            public int SizeY;
            public int SizeZ;
            public int PosX;
            public int PosY;
            public int PosZ;
            public int[,,] Voxels;
            public int this[int x, int y, int z]
            {
                get
                {
                    return this.Voxels[x, y, z];
                }
            }
            public byte NameLength
            {
                get
                {
                    return (!string.IsNullOrEmpty(this.Name) ? ((byte) this.Name.Length) : ((byte) 0));
                }
            }
        }
    }
}

